#pragma once

#include <iostream>
#include "Thread.hpp"
#include <vector>
#include <queue>
#include <pthread.h>
#include <string>
#include "Log.hpp"
#include "LockGuard.hpp"
#include "Task.hpp"

using namespace ThreadModule;

const static int gdefaultthreadnum = 3;

template <typename T>
class ThreadPool
{
private:
    ThreadPool(int threadnum = gdefaultthreadnum)
        : _threadnum(threadnum), _waitnum(0), _isrunning(false)
    {
        pthread_mutex_init(_mutex);
        pthread_cond_init(_cond);
    }
    
public:
    ~ThreadPool()
    {
        pthread_mutex_destroy(_mutex);
        pthread_cond_destroy(_cond);
    }

private:
    int _threadnum;
    std::vector<Thread> _threads;
    std::queue<T> _task_queue;
    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
    int _waitnum;
    bool _isrunning;
    static ThreadPool<T> *_tp;
    static pthread_mutex_t _mt;
};

template <typename T>
ThreadPool<T> *ThreadPool<T>::_tp = nullptr;

template <typename T>
pthread_mutex_t ThreadPool<T>::_mt = PTHREAD_MUTEX_INITIALIZER;